﻿using System;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Xsl;
using Sushi.Core;
using Exception=System.Exception;

namespace Sushi.Sample.Client.Simulator
{
   internal partial class MainForm : Form
   {
      public MainForm()
      {
         InitializeComponent();
      }

      protected override void OnLoad(EventArgs e)
      {
         base.OnLoad(e);

         try
         {
            using (var proxy = new SushiServiceProxy())
            {
               _serviceUri.Text = proxy.Endpoint.Address.Uri.AbsoluteUri;
            }
         }
         catch (Exception ex)
         {
            _serviceUri.Text = "Could not retrieve default Uri:"+ex.Message;
         }
      }

      private void OnInvokeService(object sender, EventArgs e)
      {
      	UpdateFormStatus(true, null, null, null);
			UpdateDataView(null, null);
			Application.DoEvents();

			var request = new GetReportRequest
			              	{
				//all of these values are being set from UI objects
				ReportRequest = new ReportRequest
				                	{
					Created = DateTime.Now,
					CreatedSpecified = true,
					CustomerReference = new CustomerReference
					{
						ID = _customerId.Text,
						Name = _customerName.Text
					},
					ID = Guid.NewGuid().ToString(),
					ReportDefinition = new ReportDefinition
					{
						Filters = new ReportDefinitionFilters
						{
							UsageDateRange = new Range
							{
								Begin = _dateRangeBegin.Value,
								End = _dateRangeEnd.Value
							}
						},
						Name = _reportName.Text,
						Release = _reportRelease.Text
					},
					Requestor = new Requestor
					{
						Email = _requestorEmail.Text,
						ID = _requestorId.Text,
						Name = _requestorName.Text
					}
				}
			};
         	
			//declare the variable here to scope it outside the try
			var inspector = new MessageViewerInspector();
			GetReportResponse response;
      	Cursor = Cursors.WaitCursor;
			try
			{
				//create a new instance of a proxy to the WCF service
				//This reads WCF <system.serviceModel> <client> data from the app.config
				using (var proxy = new SushiServiceProxy())
				{
					proxy.Endpoint.Behaviors.Add(inspector);
					proxy.Endpoint.Address = new EndpointAddress(_serviceUri.Text);
					response = proxy.GetReport(request);
					proxy.Close();
            }
         }
         catch (Exception ex)
         {
            response = new GetReportResponse
            {
               ReportResponse = new CounterReportResponse{Exception = ex.ToSushiExceptions().ToArray()}
            };
         }
			finally
			{
				Cursor = Cursors.Default;
			}

			var requestMessage = inspector.RequestMessage;
			var responseMessage = inspector.ResponseMessage;

			UpdateDataView(requestMessage, responseMessage);
			var exceptionCount = response.ReportResponse.Exception != null ? response.ReportResponse.Exception.Length : 0;
			var responseSize = responseMessage.Length;
      	UpdateFormStatus(false, true, exceptionCount, responseSize);
      }

      private void UpdateFormStatus(bool callingService, bool? lastResponseSuccessful, int? lastErrorCount, int? responseSize)
      {
         if (callingService)
         {
            _status.Text = "Calling Service...";
            return;
         }

         _status.Text = string.Format("Idle; Last request {0} with {1} error{2}.",
                                      lastResponseSuccessful ?? true ? "succeeded" : "failed", lastErrorCount ?? 0,
                                      lastErrorCount != 1 ? "s" : string.Empty);

			if (responseSize != null)
				_responseSize.Text = responseSize.ToString();
      }

		private void UpdateDataView(string requestMessage, string responseMessage)
      {
			responseText.DocumentText = XmlToHtml(responseMessage);
			responseText.Tag = responseMessage;


			requestText.DocumentText = XmlToHtml(requestMessage);
			requestText.Tag = requestMessage;
		}

		private void copyToolStripMenuItem_Click(object sender, EventArgs e)
		{
			var mi = (ToolStripMenuItem) sender;
			var ms = (ContextMenuStrip) mi.Owner;
			var browser =  (WebBrowser) ms.SourceControl;
			Clipboard.SetText((string)browser.Tag);
		}

#region Helper Functions

		public static string XmlToHtml(string xml)
		{
			if ((xml == null) || (xml.Trim().Length == 0)) return "";
			
			var s = new StringReader(Resource.XMLXSLT);

			var xr = XmlReader.Create(s);
			var xct = new XslCompiledTransform();
			xct.Load(xr);

			var sb = new StringBuilder();
			var xw = XmlWriter.Create(sb);

			var tr = new StringReader(xml);
			var xmlData = XmlReader.Create(tr);
			if (xw != null) xct.Transform(xmlData, xw);

			return sb.ToString();
		}


#endregion
	}
}